package controllers

import (
	"encoding/base64"
	"fmt"
	"github.com/astaxie/beego"
	"math/rand"
	"net/smtp"
	"object/go_cms/common"
	"object/go_cms/models"
	"os"
	"path"
	"regexp"
	"strconv"
	"strings"
	"time"
)

type Result struct {
	Code  int
	Msg   string
	Count int64
	Data  interface{}
}

type BaseController struct {
	beego.Controller
	Res   Result
	Cache common.Caches
}

//获取参数map
func (b *BaseController) GetParamMap() map[string]interface{} {
	maps := make(map[string]interface{})
	for key, val := range b.Input() {
		maps[key] = val[0]
	}
	return maps
}

//返回json
func (b *BaseController) Json(res interface{}) {
	b.Data["json"] = res
	b.ServeJSON()
}

//文件上传
func (c *BaseController) BaseUpload(field string, pathName string) Result {
	fileMaps := make(map[string]interface{})
	f, h, err := c.GetFile(field)
	if err != nil {
		c.Res.Code = 0
		c.Res.Msg = "没有文件上传"
		return c.Res
	}
	path_dir := pathName
	if path_dir != "" {
		path_dir += "/"
	}
	c.Res.Count = h.Size
	ext := path.Ext(h.Filename)
	fileMaps["upload_name"] = h.Filename
	fileMaps["ext"] = ext
	fileMaps["size"] = strconv.FormatInt(h.Size, 10)
	ext = strings.ToLower(ext)
	/*var AllExtMap map[string]bool = map[string]bool{
		".jpg": true, ".jpeg": true, ".png": true, ".gif": true, ".bmp": true,
		".doc": true, ".docx": true, ".xls": true, ".xlsx": true, ".ppt": true, ".pptx": true, ".pdf": true,
		".txt": true, ".md": true,
		".mp4": true, ".flv": true, ".webm": true, ".avi": true, ".mkv": true, ".mpeg": true, ".rmvb": true,
		".mp3": true, ".wav": true,
		".rar": true, ".zip": true, ".7z": true, ".tar": true,
	}*/
	// 图片：1，文档：2，视频：3，音频：4，压缩包：5
	var AllExtMap map[string]int = map[string]int{
		".jpg": 1, ".jpeg": 1, ".png": 1, ".gif": 1, ".bmp": 1, ".svg": 1, ".ico": 1,
		".doc": 2, ".docx": 2, ".xls": 2, ".xlsx": 2, ".ppt": 2, ".pptx": 2, ".pdf": 2,
		".txt": 2, ".md": 2,
		".mp4": 3, ".flv": 3, ".webm": 3, ".avi": 3, ".mkv": 3, ".mpeg": 3, ".rmvb": 3,
		".mp3": 4, ".wav": 4,
		".rar": 5, ".zip": 5, ".7z": 5, ".tar": 5,
	}
	//验证
	if AllExtMap[ext] == 0 {
		c.Res.Code = 0
		c.Res.Msg = "文件类型不符"
		return c.Res
	}
	fileMaps["type"] = strconv.Itoa(AllExtMap[ext])

	size := beego.AppConfig.String("upload_size")
	var sizeup int64 = 500 * 1024 * 1024
	if size != "" {
		sizeup, _ = strconv.ParseInt(size, 10, 64)
	}
	if h.Size > sizeup {
		c.Res.Code = 0
		c.Res.Msg = "文件大小已超过限制"
		return c.Res
	}
	//创建目录
	uploadDir := "static/upload/" + path_dir + time.Now().Format("20060102")
	fileMaps["path"] = uploadDir
	err = os.MkdirAll(uploadDir, 777)
	if err != nil {
		c.Res.Code = 0
		c.Res.Msg = err.Error()
		return c.Res
	}
	rand.Seed(time.Now().UnixNano())
	hashName := rand.Uint64()
	fileName := fmt.Sprintf("%x", hashName) + ext
	fpath := uploadDir + "/" + fileName
	fileMaps["file_name"] = fileName
	defer f.Close()
	err = c.SaveToFile(field, fpath)
	if err != nil {
		c.Res.Code = 0
		c.Res.Msg = err.Error()
		return c.Res
	}
	c.Res.Data = "/" + fpath
	c.Res.Code = 1
	c.Res.Msg = "上传成功"

	fileMaps["url"] = c.Res.Data
	fileMaps["local_type"] = "1"
	//写入数据库
	upload := models.UploadFileModels{}
	upload.Insert(fileMaps)

	return c.Res
}

// base64转换为文件,
//	param,base64编码内容
//	pathDir,保存路径
//	ext,设置后缀
func (c *BaseController) Base64ToFile(param string, pathDir string, ext string) (Result, string) {
	fileMaps := make(map[string]interface{})
	if pathDir != "" {
		pathDir = pathDir + "/"
	}
	uploadDir := "static/upload/" + pathDir + time.Now().Format("20060102")
	rand.Seed(time.Now().UnixNano())
	hashName := rand.Uint64()
	fpath := uploadDir + "/" + fmt.Sprintf("%x", hashName)
	fileMaps["path"] = uploadDir
	if ext == "" {
		ExtMap := map[string]string{
			"image/png": ".png", "image/gif": ".gif", "image/jpeg": ".jpg", "image/svg+xml": ".svg", "image/bmp": ".bmp", "image/x-icon": ".ico",
			"text/plain": ".txt",
			"video/mp4":  ".mp4", "video/flv": ".flv", "video/webm": ".webm", "video/avi": ".avi", "video/mkv": ".mkv",
			"video/mpeg": ".mpeg", "video/rmvb": ".rmvb",
			"video/mp3": ".mp3", "video/wav": ".wav",
			"application/msword": ".doc", "application/vnd.openxmlformats-officedocument.wordprocessingml.document": ".docx",
			"application/vnd.ms-excel": ".xls", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ".xlsx",
			"application/pdf":               ".pdf",
			"application/vnd.ms-powerpoint": ".ppt", "application/vnd.openxmlformats-officedocument.presentationml.presentation": ".pptx",
			"application/x-zip-compressed": ".zip", "application/octet-stream": ".rar", "application/x-gzip": ".tar.gz",
		}
		reg := regexp.MustCompile(`(?i:^data:).*;base64`)
		index := reg.FindIndex([]byte(param))
		if index != nil {
			types := param[(index[0] + 5):(index[1] - 7)]
			ext = ExtMap[types]
		}
	}
	fileMaps["ext"] = ext
	fileMaps["upload_name"] = fmt.Sprintf("%x", hashName) + ext
	fileMaps["file_name"] = fileMaps["upload_name"]
	// 图片：1，文档：2，视频：3，音频：4，压缩包：5
	var AllExtMap map[string]int = map[string]int{
		".jpg": 1, ".jpeg": 1, ".png": 1, ".gif": 1, ".bmp": 1, ".svg": 1, ".ico": 1,
		".doc": 2, ".docx": 2, ".xls": 2, ".xlsx": 2, ".ppt": 2, ".pptx": 2, ".pdf": 2,
		".txt": 2, ".md": 2,
		".mp4": 3, ".flv": 3, ".webm": 3, ".avi": 3, ".mkv": 3, ".mpeg": 3, ".rmvb": 3,
		".mp3": 4, ".wav": 4,
		".rar": 5, ".zip": 5, ".7z": 5, ".tar": 5,
	}
	fileMaps["type"] = strconv.Itoa(AllExtMap[ext])
	fpath += ext
	re, _ := regexp.Compile(`(?i:^data:).*;base64,`)
	base64Str := re.ReplaceAllString(param, "")
	bascc := strings.ReplaceAll(base64Str, " ", "+")
	by, err := base64.StdEncoding.DecodeString(bascc)
	if err != nil {
		c.Res.Code = 0
		c.Res.Msg = err.Error()
		return c.Res, ext
	}
	_, Iserr := os.Stat(uploadDir)
	if !os.IsExist(Iserr) {
		_ = os.MkdirAll(uploadDir, 0755)
	}
	f, err := os.OpenFile(fpath, os.O_RDWR|os.O_CREATE, os.ModePerm)
	defer f.Close()
	if err != nil {
		c.Res.Code = 0
		c.Res.Msg = err.Error()
		return c.Res, ext
	}
	num, errs := f.Write(by)
	if errs != nil {
		c.Res.Code = 0
		c.Res.Msg = err.Error()
		return c.Res, ext
	}
	c.Res.Code = 1
	c.Res.Data = "/" + fpath
	c.Res.Count = int64(num)

	fileMaps["size"] = strconv.Itoa(num)
	fileMaps["url"] = c.Res.Data
	fileMaps["local_type"] = "1"
	//写入数据库
	upload := models.UploadFileModels{}
	upload.Insert(fileMaps)
	return c.Res, ext
}

// 发送邮件
func (c *BaseController) SendMail(user, password, host, to, subject, body, mailtype string) bool {
	hp := strings.Split(host, ":")
	auth := smtp.PlainAuth("", user, password, hp[0])
	var content_type string
	if mailtype == "html" {
		content_type = "Content-Type: text/" + mailtype + "; charset=UTF-8"
	} else {
		content_type = "Content-Type: text/plain" + "; charset=UTF-8"
	}
	msg := []byte("To: " + to + "\r\nFrom: " + user + "<" + user + ">\r\nSubject: " + subject + "\r\n" + content_type + "\r\n\r\n" + body)
	send_to := strings.Split(to, ";")
	err := smtp.SendMail(host, auth, user, send_to, msg)
	if err != nil {
		return false
	}
	return true
}
